import struct
#文件头信息编码模式
japanese="shift-jis"
chinese="gbk" #或者gb2312
sign_mode=japanese #默认编码模式
#使用此方法重构
class Iutils:
    def get_chunk_size(file):
        chunk_size=file.read(4)
        result=int.from_bytes(chunk_size,byteorder='little', signed=False)
        #print("关键帧数量",keys)
        return result
    def set_decode_mode(mode:str):
        sign_mode=mode
#从这里传入file
def parse(file):
    vmd_object={}
    #将所有数据解析后存在一个object里面 
    vmd_object["sign"]=get_sign(file)
    vmd_object["model_name"]=get_model_name(file,vmd_object['sign'])
    #骨骼关键帧keys[]
    vmd_object['keys']=get_bone_frames(file)
    vmd_object["morph_keys"]=get_morph(file)
    vmd_object["cam_keys"]=get_camKeys(file) #todo 这一步可能代码没写完
    vmd_object["light_keys"]=get_lightKeys(file)
    return vmd_object
def get_sign(file):
    sign=file.read(30)
    sign_name=sign.decode().strip()
    return sign_name
def get_model_name(file,sign:str):
    data:bytes
    if "Vocaloid Motion Data file" in sign:
        print("v1版本")
        data=file.read(10)
    elif "Vocaloid Motion Data 0002" in sign:
        print("v2版本")
        data=file.read(20)
        split_data=data.split(b"\x00")#print("分割数据",split_data)
        if sign_mode==japanese:
            data=split_data[0].decode("shift-jis")
        elif sign_mode==chinese:
            data=split_data[0].decode("gbk")
    else:
        print("Invalid vmd file")
    print("模型名称二进制",data)
    return data
def get_bone_frames(file):
    keys=[]
    bone_key_number=Iutils.get_chunk_size(file)
    print("骨骼动画关键帧数量",bone_key_number)
    for i in range(bone_key_number):#print("指针位置",file.tell())
        key_frames={}
        key_frames["bone_name"]=get_bone_name(file)
        #关键帧持续时间?
        key_frames['frames']=get_frame_time(file)
        key_frames['translation']=get_pos(file)
        key_frames['rotation']=get_rotation(file)
        key_frames['curve']=get_curve(file)
        keys.append(key_frames)
    return keys
def get_bone_name(file):
    bone_name=file.read(15)#print(bone_name)
    bone_name=bone_name.split(b"\x00")[0]
    result=bone_name.decode("shift-jis")#print("骨骼名称",result)
    return result
def get_frame_time(file):
    frame_time=file.read(4)
    time=struct.unpack("<I",frame_time)[0]#print("关键帧时间",time)
    return time
def get_pos(file):
    pos_array=[]
    for i in range(3):
        pos=file.read(4)
        pos=struct.unpack("f",pos)[0]
        pos_array.append(pos)
    return pos_array
def get_rotation(file):
    rotation_array=[]
    for i in range(4):
        rotate=struct.unpack("f",file.read(4))[0]
        rotation_array.append(rotate)#print("骨骼旋转xyzw,",rotation_array)
    return rotation_array
#补间曲线的坐标 x y z r 16*4
def get_curve(file):
    curve=[]
    for i in range(16):
        c=file.read(4)
        c=struct.unpack("f",c)[0]
        curve.append(c)
    return curve
#表情关键帧数据块
def get_morph(file):
    morph=[]
    def get_frame_time(file):
        time=struct.unpack("<I",file.read(4))[0]
        #print("关键帧时间",time)
        return time
    def get_weight(file):
        weight=file.read(4)
        w=struct.unpack("f",weight)
        return weight
    keys_number=Iutils.get_chunk_size(file)
    print("表情关键帧数量",keys_number)
    for i in range(keys_number):
        morph_obj={}
        morph_name=file.read(15)
        morph_obj["morph_name"]=morph_name.split(b"\x00")[0]
        morph_obj["frame_time"]=get_frame_time(file)
        #权重
        morph_obj["weight"]=get_weight(file)
        morph.append(morph_obj)
    return morph
#镜头数据
def get_camKeys(file):
    def get_frame_time(file):
        frame=file.read(4)
        frame_time=struct.unpack("<I",frame)
        return frame_time
    def get_distance(file):
        d=file.read(4)
        distance=struct.unpack("<f",d)
        return distance
    def get_cam_pos(file):
        pos=[]
        for i in range(4):
            pos.append(struct.unpack("f",file.read(3)))
        print("摄像机位置数据",pos)
        return pos
    def get_cam_rot(file):
        rot=[]
        for i in range(3):
            rot.append(struct.unpack("I"),file.read(4))
        print("摄像机角度信息",rot)
        return rot
    def get_cam_curve(file):
        curve=[]
        for i in range(6):
            curve.append(struct.unpack("I"),file.read(4))
        print("摄像机补间曲线",curve)
        return curve
    def get_cam_fov(file):
        fov=struct.unpack("I",file.read(4))
        print("摄像机视角",fov)
        return fov
    def get_cam_orth(file):
        orth_enable=struct.unpack("I",file.read(4))
        print("正交模式",orth_enable)
        return orth_enable
    key_number=Iutils.get_chunk_size(file)
    print("镜头关键帧数量",key_number)
    cam_obj=[]
    if key_number==0:
        print("没有镜头关键帧,指针位置",file.tell())
        return 0
    else:
        for i in range(key_number):
            cam={}
            cam['frame_time']=get_frame_time()
            cam["distance"]=get_distance(file)
            cam['position']=get_cam_pos(file)
            cam['rotation']=get_cam_rot(file)
            cam['curve']=get_cam_curve(file)
            cam['fov']=get_cam_fov(file)#是否开启正交相机模式
            cam['orth']=get_cam_orth(file)
            cam_obj.append(cam)
        return cam_obj
def get_lightKeys(file):
    light_obj=[]
    light_key_number=Iutils.get_chunk_size(file)
    print("光线关键帧数量",light_key_number)
    if light_key_number==0:
        print("没有镜头关键帧,指针位置",file.tell())
        print("解析完毕")
        return 0
    else:
        for i in range(light_key_number):
            tmp_light={}
            light_obj.append(tmp_light)
    return light_obj
